package com.mdd.front.utils;

import com.mdd.common.config.GlobalConfig;
import com.mdd.common.utils.ConfigUtil;
import com.mdd.common.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SearchUtils {


    private static RedisTemplate redisTemplate = RedisUtil.handler();

    private static String redisPrefixe = GlobalConfig.redisPrefix;

    private static String getSearchHistoryKey(Integer userId) {
        return redisPrefixe + "search_history_user:" + userId;
    }

    /**
     * 新增一条该userId用户在搜索栏的历史记录，searchKey代表输入的关键词
     *
     * @param userId
     * @param searchKey
     * @return
     */
    public static int addSearchHistoryByUserId(Integer userId, String searchKey) {
        String searchHistoryKey = getSearchHistoryKey(userId);
        boolean flag = redisTemplate.hasKey(searchHistoryKey);
        if (flag) {
            Object hk = redisTemplate.opsForHash().get(searchHistoryKey, searchKey);
            if (hk != null) {
                return 1;
            } else {
                redisTemplate.opsForHash().put(searchHistoryKey, searchKey, "1");
            }
        } else {
            redisTemplate.opsForHash().put(searchHistoryKey, searchKey, "1");
        }
        return 1;
    }

    /**
     * 删除个人历史数据
     *
     * @param userId
     * @param searchKey
     * @return
     */
    public static long delSearchHistoryByUserId(Integer userId, String searchKey) {
        String searchHistoryKey = getSearchHistoryKey(userId);
        return redisTemplate.opsForHash().delete(searchHistoryKey, searchKey);
    }

    public static void clearSearchHistory(Integer userId) {
        String searchHistoryKey = getSearchHistoryKey(userId);
        Set<String> searchKeys =  redisTemplate.opsForHash().keys(searchHistoryKey);
        searchKeys.forEach(item -> {
            redisTemplate.opsForHash().delete(searchHistoryKey, item);
        });
    }

    /**
     * 获取个人历史数据列表
     *
     * @param userId
     * @return
     */
    public static List<String> getSearchHistoryByUserId(Integer userId) {
        List<String> history = new ArrayList<>();
        String searchHistoryKey = getSearchHistoryKey(userId);
        boolean flag = redisTemplate.hasKey(searchHistoryKey);
        if (flag) {
            Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(searchHistoryKey, ScanOptions.NONE);
            while (cursor.hasNext()) {
                Map.Entry<Object, Object> map = cursor.next();
                String key = map.getKey().toString();
                history.add(key);
            }
            return history;
        }
        return null;
    }

    /**
     * 新增一条热词搜索记录，将用户输入的热词存储下来
     *
     * @param searchKey
     * @return
     */
    public static int addHot(String searchKey) {
        Long now = System.currentTimeMillis();
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        List<String> title = new ArrayList<>();
        title.add(searchKey);
        for (int i = 0, length = title.size(); i < length; i++) {
            String tle = title.get(i);
            try {
                if (zSetOperations.score("title", tle) <= 0) {
                    zSetOperations.add("title", tle, 0);
                    valueOperations.set(tle, String.valueOf(now));
                }
            } catch (Exception e) {
                zSetOperations.add("title", tle, 0);
                valueOperations.set(tle, String.valueOf(now));
            }
        }
        return 1;
    }

    /**
     * 根据searchKey搜索其相关最热的前十名 (如果searchKey为null空，则返回redis存储的前十最热词条)
     *
     * @param searchKey
     * @return
     */
    public static List<String> getHotList(String searchKey) {
        String key = searchKey;
        Long now = System.currentTimeMillis();
        List<String> result = new ArrayList<>();

        String isHotSearch = ConfigUtil.get("search", "isHotSearch", "0");


        if (Integer.parseInt(isHotSearch) == 1) {
            ZSetOperations zSetOperations = redisTemplate.opsForZSet();
            ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
            Set<String> value = zSetOperations.reverseRangeByScore("title", 0, Double.MAX_VALUE);
            //key不为空的时候 推荐相关的最热前十名
            if (StringUtils.isNotEmpty(searchKey)) {
                for (String val : value) {
                    if (StringUtils.containsIgnoreCase(val, key)) {
                        //只返回最热的前十名
                        if (result.size() > 9) {
                            break;
                        }
                        Long time = Long.valueOf(valueOperations.get(val));
                        if ((now - time) < 2592000000L) {
                            //返回最近一个月的数据
                            result.add(val);
                        } else {
                            //时间超过一个月没搜索就把这个词热度归0
                            zSetOperations.add("title", val, 0);
                        }
                    }
                }
            } else {
                for (String val : value) {
                    if (result.size() > 9) {
                        //只返回最热的前十名
                        break;
                    }
                    Long time = Long.valueOf(valueOperations.get(val));
                    if ((now - time) < 2592000000L) {
                        //返回最近一个月的数据
                        result.add(val);
                    } else {
                        //时间超过一个月没搜索就把这个词热度归0
                        zSetOperations.add("title", val, 0);
                    }
                }
            }
        }


        return result;
    }

    /**
     * 每次点击给相关词searchKey热度 +1
     *
     * @param searchKey
     * @return
     */
    public static int incrementHot(String searchKey) {
        String key = searchKey;
        Long now = System.currentTimeMillis();
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        zSetOperations.incrementScore("title", key, 1);
        valueOperations.getAndSet(key, String.valueOf(now));
        return 1;
    }


}
